import {
  adminGuanFangGate,
  formatError,
  getUpdateHistoryTime,
  guanFangGate,
  handleSeatchTime,
  handleHistoryPositionTimeOld,
  weiTuoRuKu,
  getZhiMaPositionParams,
  getBigTime,
  chengJiaoRuKu,
  newGuanFangGate,
} from './../../util/index';
/* eslint-disable */
import { forwardRef, Inject, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { adminGate, formatPage, formatSuccess, gateRestClient, getZmKeys, orderAddHeyue } from 'src/util';
import { Between, Repository } from 'typeorm';
import { Order } from './entities/order.entity';
import { CreateOrderDto } from './dto/create-order.dto';
import { mockdata, orderInSqlParams } from 'src/util/helper';
import { GateService } from '../gate/gate.service';
import { UserService } from '../user/user.service';
import { Trade } from '../trade/entities/trade.entity';
import { Logger } from 'winston';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';

const dayjs = require('dayjs');
@Injectable()
export class OrderService {
  constructor(
    @InjectRepository(Order)
    private readonly orderRepository: Repository<Order>,
    @InjectRepository(Trade)
    private readonly tradeRepository: Repository<Trade>,
    private gateService: GateService,
    @Inject(forwardRef(() => UserService))
    private userService: UserService,
    @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
  ) {}

  // 下单
  async submitOrder(e) {
    const params: any = { ...e, settle: 'usdt' };
    const opts = { ...params };
    const res: any = (await guanFangGate.createFuturesOrder('usdt', params, opts))?.body;
    return formatSuccess(res);
  }

  // node自动爆仓用, 整key
  async nodeAutoBaoCang({ e, zhima }) {
    const { key, secret } = zhima;
    const params: any = { ...e, settle: 'usdt' };
    const opts = { ...params };
    const res: any = (await newGuanFangGate(key, secret).createFuturesOrder('usdt', params, opts))?.body;
    return formatSuccess(res);
  }

  // 下单成功后入库
  async orderToSql(createOrderDto: CreateOrderDto) {
    const data = await this.orderRepository.save(createOrderDto);
  }

  // 订单列表-芝麻官方
  async orderList(params, isAdmin = false) {
    const _params: any = {
      ...params,
      contract: '',
      limit: 100,
      offset: 0,
    };
    // 1. 查用户的芝麻key，目前只查单用户
    const users = await getZmKeys(params?.userIds, this.userService);
    if (!users || users.length === 0) return formatSuccess([]);
    const userData = users[0];
    const res = await adminGuanFangGate(userData).listFuturesOrders('usdt', _params.status, _params);
    let list: any = res.body.reverse();
    list = await orderAddHeyue(list, this.gateService);
    list.forEach((item: any, i) => {
      item.userDirection = userData?.direction;
      item.newSize = item.size * item.userDirection;
    });
    return formatSuccess(list);
  }

  // 订单列表-my
  async myOrderList(params) {
    const pageNum = params.pageNum || 1;
    const pageSize = params.pageSize || 10;
    // 查询条件
    const where: any = {};
    if (params?.level) where.level = params?.level;
    // 获取总条数
    const total = await this.orderRepository.count({ where });
    // 查第几页的数据
    let list = [];
    if (total > 0) {
      list = await this.orderRepository.find({
        skip: (pageNum - 1) * pageSize,
        take: pageSize,
        where,
        order: { create_time: 'DESC' },
      });
    }
    return formatPage({ pageNum, pageSize, total, list });
  }

  // 历史订单-旧
  async historyOrderOld(params) {
    const _params: any = {
      ...params,
      contract: '',
      settle: 'usdt',
      status: 'finished', // open当前委托, finished历史委托
      limit: 1000,
      offset: 0,
    };
    let res: any;
    // 1. 查用户的芝麻key，目前只查单用户
    const users = await getZmKeys(params?.userIds, this.userService);
    if (!users || users.length === 0) return formatSuccess([]);
    const userData = users[0];
    res = await adminGate(userData).getFuturesOrdersByTimeRange(_params);
    let list: any = res;
    list = await orderAddHeyue(list, this.gateService);
    list.forEach((item: any, i) => {
      item.userDirection = userData?.direction;
      item.newSize = item.size * item.userDirection;
    });
    return formatSuccess(list);
  }

  // 历史订单-芝麻
  async historyOrder({ from, to, userIds }: any) {
    const users = await getZmKeys(userIds, this.userService);
    if (!users || users.length === 0) return formatSuccess([]);
    const userData: any = users[0];
    // 获取查询时间范围
    const timeData = handleHistoryPositionTimeOld({ from, to, userCreateTime: userData?.create_time });
    const params: any = {
      from: timeData?.from,
      to: timeData?.to,
      contract: '',
      settle: 'usdt',
      status: 'finished', // open当前委托, finished历史委托
      limit: 1000,
      offset: 0,
    };
    const { key, secret } = userData;
    const res = await adminGate({ key, secret }).getFuturesOrdersByTimeRange(params);
    let list: any = res;
    // 添加合约信息
    list = await orderAddHeyue(list, this.gateService);
    list.forEach((item: any, i) => {
      // 新增
      item.userData = userData;
      item.userId = userData?.id;
      item.userName = userData?.name;
      item.userDirection = userData?.direction;
      // 修改
      item.gateid = item?.id;
      item.newSize = item.size * item.userDirection;
      item.finishTimeNew = dayjs(item.finish_time * 1000).format('YYYY-MM-DD HH:mm:ss');
      item.geateCreateTime = item?.create_time;
      item.geateUpdateTime = item?.update_time;
    });
    return formatSuccess(list);
  }

  // 历史订单新-黑洞-前后台查询用
  async myHistoryOrder({ userIds, startTime = null, endTime = null, justMyData = false }) {
    const userId = userIds[0];
    // 处理时间问题
    // 1. api: 查用户的芝麻key，目前只查单用户
    const users = await getZmKeys(userIds, this.userService);
    if (!users || users.length === 0) return formatSuccess([]);
    const userData = users[0];
    const { startTime: _startTime, endTime: _endTime } = handleSeatchTime({ startTime, endTime, userCreateTime: userData?.create_time });
    // 查询条件
    const where: any = {};
    if (userId) where.userId = userId;
    where.finishTimeNew = Between(_startTime, _endTime);
    const arr = await this.orderRepository.find({
      where,
      order: { finishTimeNew: 'DESC' },
    });
    const list = arr.map((item: any) => ({
      ...item,
      contractInfo: JSON.parse(item?.contractInfo),
    }));
    // 2.是否查询芝麻历史仓位
    const timeInfo = getZhiMaPositionParams(userData);
    const bigTime = getBigTime(_endTime, timeInfo?.startTime);
    let zhimaDatas = [];
    if (!justMyData && bigTime === _endTime) {
      zhimaDatas = (await this.historyOrder(timeInfo))?.data;
    }
    const zhiMaTotal = zhimaDatas?.length;
    const _list = [...zhimaDatas, ...list];
    return formatSuccess({
      list: _list,
      total: _list.length,
      timeInfo,
      zhiMaTotal,
      zhimaDatas,
      heiDongTotal: list.length,
    });
  }

  // 撤单
  async delOrder(id: any) {
    const params: any = {
      settle: 'usdt',
      order_id: id,
    };
    console.log('撤单id', id);
    const res: any = await gateRestClient.cancelFuturesOrder(params);
    return formatSuccess(res);
  }

  // ===== 后台系统,给用户的ids，自动处理

  // 后台订单列表,
  async htOrderList(params) {
    return await this.orderList(params, true);
  }

  // 定时同步芝麻的历史委托
  async tongBuWeituo({ date = null }) {
    console.log('==== 开始同步历史委托，date', date);
    const tongBuDate = date; // 同步日期
    // 1. 获取用户列表，筛选有芝麻的用户
    const users = (await this.userService.findAll({}))?.data?.list?.filter((item) => item?.zhima);
    const userIds = users.map((item) => item.id);
    console.log('userIds: 获取用户列表，筛选有芝麻的用户', userIds);
    // 2. 获取历史委托
    const weituoParams = getUpdateHistoryTime(users, tongBuDate); // 处理时间
    console.log('参数：查询时间 ');
    const weituoApis = weituoParams.map(({ userIds, from, to }) => this.historyOrder({ userIds, from, to }));
    const weituoRes = await Promise.allSettled(weituoApis);
    const aYuanShiArr = weituoRes.map((item: any) => item?.value?.data || []);
    let allList = [];
    aYuanShiArr.map((item) => {
      allList = [...allList, ...item];
    });
    // console.log('== 同步: 获取历史委托-end', allList.length);
    // 3. 将历史委托入库
    const rukudata = await weiTuoRuKu(allList, this.orderRepository);
    // const rukudata: any = {}; // 测试
    if (!rukudata.success) console.log('入库失败');
    console.log('===将历史委托入库完成 ==');
    // 计算入库数量，更新同步表
    const weiTuoNums = {};
    userIds.map((user, i) => {
      weiTuoNums[user] = aYuanShiArr[i]?.length || 0;
    });
    console.log('历史委托入库数据: weiTuoNums: ', weiTuoNums);
    this.logger.info(`orderService: 历史委托入库数据-${JSON.stringify(weiTuoNums)}`);
    console.log('==============');
    return formatSuccess({
      users,
      weituoParams,
      aYuanShiArr,
      list: allList,
      weiTuoNums,
    });
  }

  // 删除历史委托,默认删除所有
  async delWeiTuos(list: any = null) {
    let datas = list;
    if (!list) datas = await this.orderRepository.find();
    const ids = datas.map(({ id }) => +id);
    await this.orderRepository.delete(ids);
    return formatSuccess(true);
  }

  // 成交记录-芝麻
  async myTrades({ userIds, from, to }: any) {
    const params: any = {
      userIds,
      from,
      to,
      settle: 'usdt',
      limit: 1000,
      offset: 0,
    };
    // const res: any = await gateRestClient.getFuturesTradingHistoryByTimeRange(params);
    let res: any;
    // 1. 查用户的芝麻key，目前只查单用户
    const users = await getZmKeys(params?.userIds, this.userService);
    if (!users || users.length === 0) return formatSuccess([]);
    const userData = users[0];
    res = await adminGate(userData).getFuturesTradingHistoryByTimeRange(params);
    let list: any = res;
    list = await orderAddHeyue(list, this.gateService);
    list.forEach((item: any, i) => {
      item.id = `ts${i + 1}`;
      item.userData = userData;
      item.userId = userData?.id;
      item.userName = userData?.name;
      item.userDirection = userData?.direction;
      item.newSize = item.size * item.userDirection;
      item.createTimeNew = dayjs(item.create_time * 1000).format('YYYY-MM-DD HH:mm:ss');
    });
    return formatSuccess(list);
  }

  // 成交记录-我的
  async myTradesNew({ userIds, startTime = null, endTime = null, justMyData = false }) {
    console.log('成交记录-我的');
    const userId = userIds[0];
    // 处理时间问题
    // 1. api: 查用户的芝麻key，目前只查单用户
    const users = await getZmKeys(userIds, this.userService);
    if (!users || users.length === 0) return formatSuccess([]);
    const userData = users[0];
    const { startTime: _startTime, endTime: _endTime } = handleSeatchTime({ startTime, endTime, userCreateTime: userData?.create_time });
    // 查询条件
    const where: any = {};
    if (userId) where.userId = userId;
    where.createTimeNew = Between(_startTime, _endTime);
    const arr = await this.tradeRepository.find({
      where,
      order: { createTimeNew: 'DESC' },
    });
    const list = arr.map((item) => ({
      ...item,
      contractInfo: JSON.parse(item?.contractInfo),
    }));
    // 2.是否查询芝麻数据
    const timeInfo = getZhiMaPositionParams(userData);
    const bigTime = getBigTime(_endTime, timeInfo?.startTime);
    let zhimaDatas = [];
    if (!justMyData && bigTime === _endTime) {
      console.log('查芝麻数据');
      zhimaDatas = (await this.myTrades(timeInfo))?.data;
    }
    const zhiMaTotal = zhimaDatas?.length;
    const _list = [...zhimaDatas, ...list];
    return formatSuccess({
      list: _list,
      total: _list.length,
      timeInfo,
      zhiMaTotal,
      zhimaDatas,
      heiDongTotal: list.length,
    });
  }

  // 定时同步芝麻的成交记录
  async tongBuChengJiao({ date = null }) {
    console.log('==== 开始同步成交记录，date', date);
    const tongBuDate = date; // 同步日期
    // 1. 获取用户列表，筛选有芝麻的用户
    const users = (await this.userService.findAll({}))?.data?.list?.filter((item) => item?.zhima);
    const userIds = users.map((item) => item.id);
    console.log('== 同步：获取用户-end');
    // 2. 获取成交记录
    const chengJiaoParams = getUpdateHistoryTime(users, tongBuDate); // 处理时间
    console.log('参数：查询时间 ');
    const getChengJiao = chengJiaoParams.map(({ userIds, from, to }) => this.myTrades({ userIds, from, to }));
    const getChengRes = await Promise.allSettled(getChengJiao);
    const aYuanShiArr = getChengRes.map((item: any) => item?.value?.data || []);
    let allList = [];
    aYuanShiArr.map((item) => {
      allList = [...allList, ...item];
    });
    console.log('== 同步: 成交记录-end');
    // 3. 将成交记录入库
    const rukudata = await chengJiaoRuKu(allList, this.tradeRepository);
    // const rukudata: any = {};
    if (!rukudata.success) console.log('入库失败');
    console.log('===将历成交记录入库完成 ==');
    // 计算入库数量
    const rukuNums = {};
    userIds.map((user, i) => (rukuNums[user] = aYuanShiArr[i]?.length || 0));
    console.log('历史成交入库数据：rukuNums: ', rukuNums);
    this.logger.info(`orderService: 历史成交入库数据-${JSON.stringify(rukuNums)}`);
    return formatSuccess({
      users,
      chengJiaoParams,
      aYuanShiArr,
      list: allList,
      rukudata,
      rukuNums,
    });
  }

  // 删除成交记录,默认删除所有
  async delChengJiaos(list: any = null) {
    let datas = list;
    if (!list) datas = await this.tradeRepository.find();
    const ids = datas.map(({ id }) => +id);
    await this.tradeRepository.delete(ids);
    return formatSuccess(true);
  }
  // 删除所有成交记录
  // async delChengJiaos() {
  // const datas = await this.tradeRepository.find();
  // const arr = datas.map(({ id }) => this.tradeRepository.delete({ id }));
  // const res = await Promise.allSettled(arr);
  // const success = res.every((item) => item.status === 'fulfilled');
  // return success ? formatSuccess({ success }) : formatError({ msg: '删除失败' });
  // }
}
